package com.brayan.webapp.model.usermgmt;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.validation.constraints.NotNull;

import org.apache.log4j.Logger;
import org.hibernate.validator.constraints.NotBlank;

import com.brayan.webapp.model.general.geoinfo.GeoInfo;

@Entity
public class Visit {

	private static Logger LOGGER = Logger.getLogger(Visit.class);

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@ManyToOne(fetch = FetchType.EAGER, optional = true, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinColumn(name = "userId")
	private User user;

	@OneToOne(optional = true)
	private GeoInfo geoInfo;
	@NotNull
	@NotBlank
	private String ipAddress;

	@OneToMany(orphanRemoval = true, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
	private List<UriAccess> uriAccessList = new ArrayList<UriAccess>();

	/** the browser agent. */
	private String clientAgent;

	@SuppressWarnings("unused")
	private Date dateCreated;
	@SuppressWarnings("unused")
	private Date dateModified;
	/** When this object is finaly persisted */
	private Date dateEnd;

	/***** EVENT HOOKS *****/
	@PrePersist
	protected void onCreate() {
		dateCreated = new Date();
	}

	@PreUpdate
	protected void onUpdate() {
		dateModified = new Date();
	}

	public void addToUriAccessList(UriAccess uriAccess) {
		if (uriAccess != null) {
			if (uriAccess.getAccessTime() == null)
				uriAccess.setAccessTime(new Date());
			uriAccessList.add(uriAccess);
			LOGGER.info("Logged a URI resource access: " + uriAccess.getUri());
		} else {
			LOGGER.error("While logging a uri resource access a given uriAccess object is null.");
		}
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public GeoInfo getGeoInfo() {
		return geoInfo;
	}

	public void setGeoInfo(GeoInfo geoInfo) {
		this.geoInfo = geoInfo;
	}

	public String getIpAddress() {
		return ipAddress;
	}

	public void setIpAddress(String ipAddress) {
		this.ipAddress = ipAddress;
	}

	public String getClientAgent() {
		return clientAgent;
	}

	public void setClientAgent(String clientAgent) {
		this.clientAgent = clientAgent;
	}

}
